package com.binguo.wxapi.baidu;

import com.binguo.common.exception.ServiceException;
import com.binguo.common.util.ImageBase64Util;
import com.binguo.common.util.ImageUtil;
import com.binguo.common.util.JsonUtil;
import com.binguo.common.util.LoggerUtil;
import com.binguo.model.mapper.*;
import com.binguo.model.model.*;
import com.binguo.wxapi.baidu.model.BaiduRecResult;
import com.binguo.wxapi.baidu.model.Results;
import com.binguo.youtu.sign.Base64Util;
import com.binguo.yprecapi.YpRecService;
import org.json.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import tk.mybatis.mapper.entity.Condition;

@Component
public class BaiduEasyDLUtil implements InitializingBean {

    private static String appid = "16805085";
    private static String apiKey = "3t7PQUPeThDcPyEpUNh8UHZA";
    private static String securityKey = "SciYNqyHOip2GnS5jDjw5nCgeaqFA85w";

    public static String tokenKey = "baiduEasyDlToken";
    private static String urlKey = "baiduEasyDlUrl";
    private static Long tokenExpireTime = 0l;

    @Resource
    private ShopBaiduUrlMapper shopBaiduUrlMapper;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;


    @Resource
    private LogProductImgMapper logProductImgMapper;
    @Resource
    private ProductMapper productMapper;

    @Resource
    private BaiduRecUtil baiduRecUtil;
    @Resource
    private YpRecService ypRecService;

    @Resource
    ShopProductRefMapper shopProductRefMapper;
    @Resource
    RecipMapper recipMapper;

    @Resource
    BranchMapper branchMapper;
    @Resource
    ShopMapper shopMapper;

    private static String localRecIp = null;
    private static String productYPRecIpAddress = null;


    public void setKey(String key, String value, long time){
        redisTemplate.opsForValue().set(key, value, time, TimeUnit.MILLISECONDS);
    }


    public Object getKey(String key){
        return redisTemplate.opsForValue().get(key);
    }


    public String getBaiduToken(Integer shopId, Integer branchId){
        Object tokenObj = getKey(tokenKey + shopId + branchId);

        if (tokenObj == null) {
            Condition condition = new Condition(ShopBaiduUrl.class);

            condition.or().andEqualTo("shopId", shopId);

            List<ShopBaiduUrl> shopBaiduUrlList = shopBaiduUrlMapper.selectByCondition(condition);
            if (shopBaiduUrlList != null && shopBaiduUrlList.size() > 0) {
                ShopBaiduUrl easyDlObj = null;

                if (branchId != null) {
                    for (ShopBaiduUrl shopBaiduUrl : shopBaiduUrlList) {
                        if (shopBaiduUrl.getUrlType() != null && shopBaiduUrl.getUrlType().intValue() == 1
                                && branchId.equals(shopBaiduUrl.getBranchId())
                                ) {
                            easyDlObj = shopBaiduUrl;
                            break;
                        }
                    }
                }else {
                    for (ShopBaiduUrl shopBaiduUrl : shopBaiduUrlList) {
                        if (shopBaiduUrl.getUrlType() != null && shopBaiduUrl.getUrlType().intValue() == 1) {
                            easyDlObj = shopBaiduUrl;
                            break;
                        }
                    }
                }

                if (easyDlObj == null) {
                    if (branchId != null) {
                        for (ShopBaiduUrl shopBaiduUrl : shopBaiduUrlList) {
                            if (shopBaiduUrl.getUrlType() != null && shopBaiduUrl.getUrlType().intValue() == 1) {
                                easyDlObj = shopBaiduUrl;
                                break;
                            }
                        }
                    }
                    if (easyDlObj == null) {
                        return "";
                    }
                }


                String token = getAuth(easyDlObj.getApiKey(), easyDlObj.getSecurityKey());

                token = URLEncoder.encode(token);

                setKey(tokenKey + shopId + branchId, token, tokenExpireTime - 6000);

                setKey(urlKey + shopId + branchId, easyDlObj.getBaiduUrl(), tokenExpireTime - 6000);


                return token;
            } else {
                return null;
            }
        }else {
            return tokenObj.toString();
        }

    }



    /**
     * 检测
     */
    public Boolean detection(String filepath, Integer shopId, Integer productId, Integer branchId){
        return detection(filepath, shopId, productId, branchId, false);
    }


    /**
     * 检测
     */
    public Boolean detection(String filepath, Integer shopId, Integer productId, Integer branchId, boolean fromSource){
        String token = getBaiduToken(shopId, branchId);
        String url = (String)getKey(urlKey + shopId + branchId);
        if (url == null || token == null) {
            return  null;
        }
        url = url + "?access_token=" + token;

        HttpHeaders DEFAULT_JSON_HEADER = new HttpHeaders();
        MediaType jsontype = MediaType.APPLICATION_JSON;
        DEFAULT_JSON_HEADER.setContentType(jsontype);
        String localFilepath = "/opt/img/" + shopId;

        Shop shop = shopMapper.selectByPrimaryKey(shopId);

        if (shop.getProductRecType() != null && shop.getProductRecType().intValue() == 4) {
            localFilepath = "/data/html/img/" + shopId;
        }
        if (shop.getProductRecType() != null && shop.getProductRecType().intValue() == 5) {
            localFilepath = "/data/html/img/" + shopId;
        }

        File file = new File(localFilepath);

        if (!file.exists()) {
            file.mkdir();
        }

        localFilepath += "/" + productId;

        file = new File(localFilepath);

        if (!file.exists()) {
            file.mkdir();
        }

        localFilepath += "/temp";

        file = new File(localFilepath);

        if (!file.exists()) {
            file.mkdir();
        }

        String tempPath = localFilepath + "/" + shopId + "_" + productId + "_" + UUID.randomUUID();

        localFilepath = tempPath + ".png";

        com.alibaba.fastjson.JSONObject json = new com.alibaba.fastjson.JSONObject();
        json.put("image", ImageBase64Util.netImage(filepath, localFilepath));
        String requestBody = json.toJSONString();

//        System.out.println(requestBody);
        try {
            HttpEntity<String> entity = new HttpEntity<>(requestBody, DEFAULT_JSON_HEADER);

            ResponseEntity<String> result = new RestTemplate().postForEntity(url, entity, String.class);

            System.out.println(result.getBody());

            BaiduRecResult baiduRecResult = JsonUtil.parse(result.getBody(), BaiduRecResult.class);

            if (baiduRecResult.getResults() != null && baiduRecResult.getResults().size() > 0) {
                int i = 0;
                boolean flag = false;
                Results tempResult = null;
                double score = 0;

                for (Results results : baiduRecResult.getResults()) {
                    if (results.getScore() > score) {
                        score = results.getScore();
                        tempResult = results;
                    }
                }

                if (score > 0.2 && tempResult != null) {

                    flag = true;
                    String cutImgPath = tempPath + "cut" + i++ + ".png";

                    int cut = 10;
                    /*ImageUtil.cutImage(localFilepath, cutImgPath
                            , tempResult.getLocation().getLeft(),
                            tempResult.getLocation().getTop(), tempResult.getLocation().getWidth(), tempResult.getLocation().getHeight());*/
                    ImageUtil.cutImageWithResize(localFilepath, cutImgPath
                            , tempResult.getLocation().getLeft() + cut,
                            tempResult.getLocation().getTop() + cut, tempResult.getLocation().getWidth() - cut, tempResult.getLocation().getHeight() - cut, 401);
                    LogProductImg logProductImg = new LogProductImg();

                    String cont_sign = null;
                    if (shop.getProductRecType() != null && shop.getProductRecType().intValue() == 4) {
                        LoggerUtil.console.info("ypRecService.addImg:" + cutImgPath);
                        logProductImg.setImgCutNetUrl(cutImgPath.replaceAll("/data/html/", "http://binguoai.com:8019/"));
                        ypRecService.addImg(logProductImg.getImgCutNetUrl(), branchId, productId, localRecIp);
                    }else if (shop.getProductRecType() != null && shop.getProductRecType().intValue() == 5) {
                        LoggerUtil.console.info("ypRecService.addImg:" + cutImgPath);
                        logProductImg.setImgCutNetUrl(cutImgPath.replaceAll("/data/html/", "http://binguoai.com:8019/"));
                        ypRecService.addImg(logProductImg.getImgCutNetUrl(), branchId, productId,productYPRecIpAddress + ":5001");
                    }else {
                        cont_sign = baiduRecUtil.addImg(shopId, branchId, cutImgPath, shopId + "_" + productId);
                        logProductImg.setImgCutNetUrl(cutImgPath.replaceAll("/opt/img/", "http://binguoai.com/wxproductimg/"));
                    }

                    logProductImg.setCutImg(cutImgPath);
                    logProductImg.setProductId(productId);
                    logProductImg.setShopId(shopId);
                    logProductImg.setSourceImg(filepath);
                    logProductImg.setContSign(cont_sign);
                    logProductImg.setCreateTime(new Date());
                    logProductImg.setBaiduDeleted(0);
                    logProductImg.setFromWxUpload(1);
                    logProductImg.setBranchId(branchId);

                    logProductImgMapper.insert(logProductImg);

                    Product product = new Product();
                    product.setProductpic(filepath);
                    product.setId(productId);
                    productMapper.updateByPrimaryKeySelective(product);

                    if (fromSource) {
                        /**
                         *
                         */
                        Condition condition = new Condition(ShopProductRef.class);
                        condition.or().andEqualTo("shopId", product.getShopid());
                        condition.or().andEqualTo("refShopId", product.getShopid());

                        List<ShopProductRef> shopProductRefList = shopProductRefMapper.selectByCondition(condition);

                        if (shopProductRefList != null && shopProductRefList.size() > 0) {

                            for (ShopProductRef shopProductRef : shopProductRefList) {

                                Integer targetShopId = null;
                                if (shopProductRef.getShopId().equals(product.getShopid())) {

                                    targetShopId = shopProductRef.getRefShopId();
                                }else {
                                    targetShopId = shopProductRef.getShopId();
                                }

                                Product sourceProduct = productMapper.selectByPrimaryKey(productId);

                                Condition productConditon = new Condition(Product.class);
                                productConditon.or().andEqualTo("shopid", targetShopId)
                                        .andEqualTo("searchcode", sourceProduct.getSearchcode())
                                ;
                                List<Product> productList = productMapper.selectByCondition(productConditon);
                                if (productList != null && productList.size() > 0) {

                                    Product targetProduct = productList.get(0);

                                    Condition branchCondtion = new Condition(Branch.class);
                                    branchCondtion.or().andEqualTo("shopId", targetShopId);
                                    List<Branch> branchList = branchMapper.selectByCondition(branchCondtion);
                                    Integer targetBranchId = null;
                                    if (branchList != null && branchList.size() > 0) {
                                        targetBranchId = branchList.get(0).getBranchId();
                                    }

                                    String target_cont_sign = baiduRecUtil.addImg(targetShopId, targetBranchId, cutImgPath, targetShopId + "_" + targetProduct.getId());

                                    Product temp = new Product();
                                    temp.setId(targetProduct.getId());
                                    temp.setProductpic(filepath);
                                    productMapper.updateByPrimaryKeySelective(temp);

                                    LogProductImg targetLogProductImg = new LogProductImg();
                                    targetLogProductImg.setCutImg(cutImgPath);
                                    targetLogProductImg.setProductId(targetProduct.getId());
                                    targetLogProductImg.setShopId(targetShopId);
                                    targetLogProductImg.setSourceImg(filepath);
                                    targetLogProductImg.setContSign(target_cont_sign);
                                    targetLogProductImg.setCreateTime(new Date());
                                    targetLogProductImg.setBaiduDeleted(0);
                                    targetLogProductImg.setFromWxUpload(1);
                                    targetLogProductImg.setBranchId(branchId);

                                    logProductImgMapper.insert(targetLogProductImg);
                                }


                            }
                        }
                    }



                }
                return flag;
            } else {

                if (shopId == 163 || (shop.getUseFullImg() != null && shop.getUseFullImg().intValue() == 1)) {//
                    String cont_sign = baiduRecUtil.addImg(shopId, branchId, localFilepath, shopId + "_" + productId);

                    LogProductImg logProductImg = new LogProductImg();
                    logProductImg.setCutImg(filepath);
                    logProductImg.setProductId(productId);
                    logProductImg.setShopId(shopId);
                    logProductImg.setSourceImg(filepath);
                    logProductImg.setContSign(cont_sign);
                    logProductImg.setCreateTime(new Date());
                    logProductImg.setFromWxUpload(1);
                    logProductImg.setBaiduDeleted(0);
                    logProductImg.setBranchId(branchId);

                    logProductImgMapper.insert(logProductImg);

                    Product product = new Product();
                    product.setProductpic(filepath);
                    product.setId(productId);
                    productMapper.updateByPrimaryKeySelective(product);

                    return true;
                }else{
                    throw new ServiceException("未识别菜品");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * 获取API访问token
     * 该token有一定的有效期，需要自行管理，当失效时需重新获取.
     * @param ak - 百度云官网获取的 API Key
     * @param sk - 百度云官网获取的 Securet Key
     * @return assess_token 示例：
     * "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
     */
    public static String getAuth(String ak, String sk) {
        // 获取token地址
        String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
        String getAccessTokenUrl = authHost
                // 1. grant_type为固定参数
                + "grant_type=client_credentials"
                // 2. 官网获取的 API Key
                + "&client_id=" + ak
                // 3. 官网获取的 Secret Key
                + "&client_secret=" + sk;
        try {
            URL realUrl = new URL(getAccessTokenUrl);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.err.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String result = "";
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            /**
             * 返回结果示例
             */
            System.err.println("result:" + result);
            JSONObject jsonObject = new JSONObject(result);
            String access_token = jsonObject.getString("access_token");
            tokenExpireTime = jsonObject.getLong("expires_in");
            return access_token;
        } catch (Exception e) {
            System.err.printf("获取token失败！");
            e.printStackTrace(System.err);
        }
        return null;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        List<Recip> recipList = recipMapper.selectAll();
        if (recipList != null && recipList.size() > 0) {
            localRecIp = recipList.get(0).getAddress();

            for (Recip recip : recipList) {
                if (recip.getIpType() != null && recip.getIpType().intValue() == 1) {
                    productYPRecIpAddress = recip.getAddress();
                    break;
                }
            }
        }
    }
}
